package com.ficus.road.maintain.service;

import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ficus.road.maintain.core.model.*;
import com.ficus.road.maintain.core.model.coverage.RoadCoverageYT;
import com.ficus.road.maintain.core.model.smartnew.PrimaryRoadSectionDTO;
import com.ficus.road.maintain.core.model.smartnew.SmartValuation;
import com.ficus.road.maintain.core.model.zh.UnitScore;
import com.ficus.road.maintain.dao.*;
import com.ficus.road.maintain.dao.coverage.RoadCoverageYTDao;
import com.ficus.road.maintain.dao.smartnew.SmartValuationMergedDao;
import com.ficus.road.maintain.dao.smartnew.primaryScreening.PrimaryRoadSectionDao;
import com.ficus.road.maintain.service.CycleNumService;
import com.ficus.road.maintain.service.TheoryGpsService;
import com.ficus.road.maintain.util.MyDateUtil;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;

import javax.annotation.PostConstruct;
import java.io.IOException;
import java.time.Instant;
import java.time.LocalDate;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import static com.ficus.road.maintain.service.ZhonghaiClient.ZH_METHOD_COMPLAIN_REPORT;
import static com.ficus.road.maintain.service.coverage.YtCoverageTask.COVERAGE_THRESHOLD;

@Service
@Slf4j
@RequiredArgsConstructor
public class ComplainService {
    @Autowired
    private HitRoadCorrelationDao hitRoadCorrelationDao;
    @Autowired
    private GetRoadPCIAndPQIDao getRoadPCIAndPQIDao;
    @Autowired
    private SmartValuationMergedDao smartValuationMergedDao;
    @Autowired
    private PrimaryRoadSectionDao primaryRoadSectionDao;
    @Autowired
    private ZhongHaiService zhongHaiService;
    //沥青路面：路面裂缝，路面龟裂，路面沉陷，路面坑塘，路面车辙
    public List<String> asphalts = new ArrayList<>(Arrays.asList("PIC_CRACK_RESULT_PIC_CRACK", "PIC_CRACK_RESULT_CRACKED",
            "PIC_POTHOLES_RESULT_SETTLEMENT", "PIC_POTHOLES_RESULT_DEPRESSION",
            "PIC_CRACK_RESULT_CAR_RUT"));
    //水泥路面：路面裂缝，板块碎裂
    public List<String> cements = new ArrayList<>(Arrays.asList("PIC_CRACK_RESULT_PIC_CRACK", "PIC_CRACK_RESULT_BROKEN_BOARD"));


    /**
     * 获取道路类型
     *
     * @param road 道路名称
     * @return 道路类型
     */
    public String getRoadType(String road) {
        Criteria roadName1 = Criteria.where("road_name").is(road);
        Query queryFindType = new Query(roadName1);
        SmartValuation one = smartValuationMergedDao.findOne(queryFindType);
        if (!(one == null)) {
            return one.getRoadCharacter();
        } else {
            return null;
        }
    }

    public String getRoadType2(String road) {
        Criteria roadName1 = Criteria.where("road_name").is(road);
        Query queryFindType = new Query(roadName1);
        PrimaryRoadSectionDTO one = primaryRoadSectionDao.findOne(queryFindType);
        if (!(one == null)) {
            return one.getRoadType();
        } else {
            return null;
        }
    }

    /**
     * 智慧决策道路病害详情弹窗
     *
     * @param road       道路名称
     * @param roadType   道路类型
     * @param pageNumber 翻页
     * @param pageSize   翻页
     * @return
     */
    public RoadDistressInformation roadCorrelation(String road, String roadType, int pageNumber, int pageSize) {

        //获取当前道路拥有病害数量
        Query query;
        long aYearAgoTimestamp = System.currentTimeMillis() / 1000 - 31536000;
        int year = LocalDate.now().getYear();
        if (year % 4 == 0) {
            aYearAgoTimestamp -= 86400;
        }
        Criteria criteriaCount;
        criteriaCount = Criteria.where("attrs.roadName").is(road);
        //计算得分时并没有时间和NEW限制
//                .and("attrs.status").nin("NEW")
//                .and("first_hit_time").gte(aYearAgoTimestamp);
        if (roadType.equals("沥青路面")) {
            // 构建查询条件
            criteriaCount = criteriaCount.and("type").in(asphalts);
        } else {
            criteriaCount = criteriaCount.and("type").in(cements);
        }
        query = new Query(criteriaCount);
        Long count = hitRoadCorrelationDao.getRoadCorrelationCount(query);
        //新建返回值
        RoadDistressInformation roadDistressInformation = new RoadDistressInformation();
        roadDistressInformation.setCount(count);
        //获取当前道路的PCI和RQI
        List<GetRoadPCIAndPQIResponse> PCIlist = getRoadPCIAndPQIDao.GetRoadPCIAndPQI(road);
        Double pcis = 0.0;
        Double rqis = 0.0;
        if (!PCIlist.isEmpty()) {
            int pciNum = 0;
            int rqiNum = 0;
            for (GetRoadPCIAndPQIResponse roadP : PCIlist) {
                if (roadP.getPci() > 0) {
                    pcis += roadP.getPci();
                    pciNum++;
                }
                if (roadP.getRqi() > 0) {
                    rqis += roadP.getRqi();
                    rqiNum++;
                }
            }
            if (pcis > 0) {
                roadDistressInformation.setPCL(pcis / pciNum);
            }
            if (rqis > 0) {
                roadDistressInformation.setRQL(rqis / rqiNum);
            }
        }
        //获取当前道路的病害名称/现场图片/病害发现时间
        List<Hit> list = hitRoadCorrelationDao.RoadCorrelation(query, pageNumber, pageSize);
        for (Hit hit : list) {
            RoadDistressInformation.RoadDistress roadDistress = new RoadDistressInformation.RoadDistress();
            roadDistress.setType(hit.getType());
            roadDistress.setRoadName(road);
            roadDistress.setSceneImage(hit.getAttrs().getSceneImage());
            Instant instant = Instant.ofEpochSecond(hit.getFirstHitTime());

            Date date = Date.from(instant);
            roadDistress.setFirstHitTime(date.toString());
            roadDistressInformation.getRoadDistress().add(roadDistress);
        }
        return roadDistressInformation;
    }


    public  ComplaintResponse getComplaintReport(ZhongHai zhongHai,int pageNumber,int pageSize,int year,int month){

        String fMonth = String.format("%02d", month);
        String fYear=String.valueOf(year);

        String rlt = zhongHaiService.getZhongHaiData(zhongHai);

        if(ObjectUtils.isEmpty(rlt))
        {
            return null;
        }

        int startIndex = rlt.indexOf("<return>") + 8;
        int endIndex = rlt.indexOf("</return>", startIndex);

        String jsonStr = rlt.substring(startIndex, endIndex);

        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

        try {
            List<ComplaintReport> reportList = objectMapper.readValue(jsonStr, objectMapper.getTypeFactory().constructCollectionType(List.class, ComplaintReport.class));
            // 按 month 和 year 分组，并计算每个事件类型的总量
            Map<String, Map<String, Integer>> groupedEvents = reportList.stream().filter(item->item.getYear().equals(fYear) && item.getMonth().equals(fMonth))
                    .collect(Collectors.groupingBy(ComplaintReport::getMonth,
                            Collectors.groupingBy(ComplaintReport::getYear,
                                    Collectors.summingInt(ComplaintReport::getNum))));


            List<ComplaintReport> collect = reportList.stream().filter(item -> item.getYear().equals(fYear) && item.getMonth().equals(fMonth)).collect(Collectors.toList());

            List<ComplaintReport> collectPage = collect.stream()
                    // 跳过前面 (pageNum - 1) * pageSize 条记录
                    .skip((pageNumber - 1) * pageSize)
                    // 限制返回的记录数为 pageSize
                    .limit(pageSize)
                    .collect(Collectors.toList());

            // 为每个事件计算占比
            collectPage.forEach(event -> {
                // 获取当前事件所在的月份和年份
                String tmonth = event.getMonth();
                String tyear = event.getYear();

                // 计算该月该类型的总量
                Integer totals = groupedEvents.get(tmonth).get(tyear);

                // 计算该事件在当前月该类型事件中的占比
                double percentage = Math.round((double) event.getNum() / totals * 10000) / 100.0;

                // 设置占比
                event.setPercentage(percentage);
            });

            ComplaintResponse complaintResponse = new ComplaintResponse();
            complaintResponse.setList(collectPage);
            complaintResponse.setTotal(collect.size());
            return complaintResponse;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }


}
